package com.stox.services.data.downloader.bse;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;

import com.stox.services.data.downloader.bse.ws.BSEChartWebService;
import com.stox.services.data.downloader.bse.ws.BSEChartWebServiceSoap;
import com.stox.services.data.downloader.bse.ws.Values;
import com.stox.services.data.downloader.model.AbstractScripDataDownloader;
import com.stox.shared.core.model.Bar;
import com.stox.shared.core.model.Scrip;
import com.stox.shared.core.model.enumeration.BarSpan;
import com.stox.shared.core.model.intf.Callback;

public class BseScripDataDownloader extends AbstractScripDataDownloader {
	
	public static final BseScripDataDownloader INSTANCE = new BseScripDataDownloader();
	
	private BseScripDataDownloader() {
		
	}
	
	public List<Bar> download(Scrip scrip, BarSpan barSpan, Date start){
		BSEChartWebService service = new BSEChartWebService();
		BSEChartWebServiceSoap soap = service.getBSEChartWebServiceSoap();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(start);
		//calendar.add(Calendar.DATE, -1);
		try {
			Values values = soap.getDailyDataDatabase(66, scrip.getId().intValue(), DatatypeFactory.newInstance().newXMLGregorianCalendar((GregorianCalendar)calendar));
			return convert(scrip.getId(), values);
		} catch (DatatypeConfigurationException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public Bar download(Long scripId, BarSpan barSpan){
		BSEChartWebService service = new BSEChartWebService();
		BSEChartWebServiceSoap soap = service.getBSEChartWebServiceSoap();
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -1);
		try {
			Values values = soap.getDailyDataDatabase(66, scripId.intValue(), DatatypeFactory.newInstance().newXMLGregorianCalendar((GregorianCalendar)calendar));
			List<Bar> bars = convert(scripId, values);
			return null == bars || bars.isEmpty() ? null : bars.get(0);
		} catch (DatatypeConfigurationException e) {
			e.printStackTrace();
		}
		return null;
	}

	private List<Bar> convert(Long scripId, Values values){
		int size = values.getDataInputValuesdate().getInt().size();
		List<Bar> bars = new ArrayList<>(size);
		for(int index = size - 1; index >= 0; index--){
			Bar bar = new Bar();
			bars.add(bar);
			bar.setScripId(scripId);
			bar.setDate(convert(values.getDataInputValuesdate().getInt().get(index)));
			bar.setOpen(values.getDataInputValues().getArrayOfFloat().get(0).getFloat().get(index).doubleValue());
			bar.setHigh(values.getDataInputValues().getArrayOfFloat().get(1).getFloat().get(index).doubleValue());
			bar.setLow(values.getDataInputValues().getArrayOfFloat().get(2).getFloat().get(index).doubleValue());
			bar.setClose(values.getDataInputValues().getArrayOfFloat().get(3).getFloat().get(index).doubleValue());
			bar.setVolume(values.getDataInputValues().getArrayOfFloat().get(4).getFloat().get(index).doubleValue());
		}
		return bars;
	}
	
	private final Calendar calendar = Calendar.getInstance();
	private Date convert(int epochDelta){
		synchronized(calendar){
			calendar.clear();
			calendar.set(1899, 11, 30); // BSE epoch
			calendar.add(Calendar.DATE, epochDelta);
			return calendar.getTime();
		}
	}
	
	@Override
	public void download(Scrip entity, BarSpan barSpan, Date start, Date end,
			Callback<List<Bar>, Void> callback) {

	}
	
}
